package com.nebulas.websocket.handler;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.nebulas.nettyhex.server.RuoYiNettyChannelInboundHandlerAdapter;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;


@Component
@Slf4j
@ServerEndpoint("/websocket/{msg}")
public class MyWebSocketHandler extends TextWebSocketHandler {



    /**
     * 线程安全的无序的集合
     */
    private static final CopyOnWriteArraySet<Session> SESSIONS = new CopyOnWriteArraySet<>();

    /**
     * 存储在线连接数
     */
    private static final Map<String, Session> SESSION_POOL = new HashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam(value = "msg") String msg) {
        try {
            SESSIONS.add(session);
            SESSION_POOL.put(msg, session);
           log.info("【WebSocket消息】有新的连接，总数为：" + SESSIONS.size());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @OnClose
    public void onClose(Session session,@PathParam(value = "msg") String msg) {
        try {
            SESSIONS.remove(session);
            SESSION_POOL.remove(msg);
           log.info("【WebSocket消息】连接断开，总数为：" + SESSION_POOL.size());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //后端接受消息
    @OnMessage
    public void onMessage(String message, @PathParam(value = "msg") String msg) {
        JSONObject jsonObject = JSON.parseObject(message);
        log.info("【WebSocket消息】收到客户端消息：" + message);
       // String longitude = jsonObject.getString("longitude");
       // String latitude = jsonObject.getString("latitude");
//        String value1 = jsonObject.getString("value1");
//        String value2 = jsonObject.getString("value2");
//        String value3 = jsonObject.getString("value3");
//        String value4 = jsonObject.getString("value4");
//        String deviceStatus = jsonObject.getString("deviceStatus");
//        String frequency = jsonObject.getString("frequency");
//        String signal = jsonObject.getString("signal");
//        String check = jsonObject.getString("check");
        //帧头
        byte[] frameHeader = new byte[]{(byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD, (byte) 0xEE, (byte) 0xFF};
        //设备号
        byte[] deviceId = new byte[1];
        deviceId[0] = (byte) Integer.parseInt(jsonObject.getString("deviceId"), 16);
        //设备类型
        byte[] deviceType = new byte[1];
        deviceType[0] = (byte) Integer.parseInt(Integer.toHexString(jsonObject.getString("deviceType").charAt(0)), 16);
        //经度
        byte[] longitude = intToByteArray(Integer.parseInt(Integer.toHexString(jsonObject.getInteger("longitude")), 16));
        //纬度
        byte[] latitude = intToByteArray(Integer.parseInt(Integer.toHexString(jsonObject.getInteger("latitude")), 16));
        //值1
        byte[] value1 = doubleToByteArray(Long.parseLong(Long.toHexString(Double.doubleToLongBits(jsonObject.getDoubleValue("value1"))),16));
        //值1
        byte[] value2 = doubleToByteArray( Long.parseLong(Long.toHexString(Double.doubleToLongBits(jsonObject.getDoubleValue("value2"))),16));


        ByteBuffer buffer = ByteBuffer.allocate(frameHeader.length + deviceId.length
                + deviceType.length+ longitude.length
                + latitude.length+value1.length+ value2.length
        );
        // 将aa和bb的内容放入ByteBuffer
        buffer.put(frameHeader);
        buffer.put(deviceId);
        buffer.put(deviceType);
        buffer.put(longitude);
        buffer.put(latitude);
        buffer.put(value1);
        buffer.put(value2);

        // 将ByteBuffer的内容转换为字节数组
        byte[] combined = buffer.array();
        String channelId = RuoYiNettyChannelInboundHandlerAdapter.deviceChannelMap.get(jsonObject.getString("deviceId"));
        ChannelHandlerContext channelHandlerContext = RuoYiNettyChannelInboundHandlerAdapter.map.get(channelId);

        ByteBuf buf = Unpooled.copiedBuffer( combined);
        channelHandlerContext.writeAndFlush(buf);
        HashMap<String, String> info = new HashMap<>();
        info.put("type", "data");
        info.put("message", "我收到了你的数据");
        sendOneMessage(msg, info);

    }
    public static byte[] doubleToByteArray(double value) {
        ByteBuffer buffer = ByteBuffer.allocate(Double.BYTES); // 分配8个字节的缓冲区
        buffer.putDouble(value); // 将double值写入缓冲区
        return buffer.array(); // 返回缓冲区的字节数组
    }

    public static byte[] intToByteArray(int value) {
        ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES); // 分配4个字节的缓冲区
        buffer.putInt(value); // 将double值写入缓冲区
        return buffer.array(); // 返回缓冲区的字节数组
    }
    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }
    /**
     * 此为广播消息
     *
     * @param message 消息
     */
    public static void sendAllMessage(String message) {
       log.info("【WebSocket消息】广播消息：" + message);
        for (Session session : SESSIONS) {
            try {
                if (session.isOpen()) {
                    session.getAsyncRemote().sendText(message);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 此为单点消息
     *
     * @param userId  用户编号
     * @param message 消息
     */
    public void sendOneMessage(String userId, Map<String,String> message) {
        Session session = SESSION_POOL.get(userId);
        if (session != null && session.isOpen()) {
            try {
                synchronized (session) {
                   // log.info("【WebSocket消息】单点消息：" + message.get("message"));
                    session.getAsyncRemote().sendText(JSON.toJSONString(message));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 此为单点消息(多人)
     *
     * @param userIds 用户编号列表
     * @param message 消息
     */
    public void sendMoreMessage(String[] userIds, String message) {
        for (String userId : userIds) {
            Session session = SESSION_POOL.get(userId);
            if (session != null && session.isOpen()) {
                try {
                   // log.info("【WebSocket消息】单点消息：" + message);
                    session.getAsyncRemote().sendText(message);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
